﻿using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using CtefCrmImport.Common.Interfaces;
using CtefCrmImport.Common.Extensions;
using CtefCrmImport.Common.Models;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Crm.Sdk.Samples;

namespace CtefCrmImport.Common.Operations
{
    public class ImportEmailsOnly
    {
        private readonly ILogger logger;
        private readonly CommonOperations common;
        private readonly OptionSetValue contactType;
        private IDictionary<string, EntityReferenceCollection> emailContactMap;

        private ServerConnection.Configuration config;

        public ImportEmailsOnly(ILogger logger, ServerConnection.Configuration config, string contactType)
        {
            this.logger = logger;
            common = new CommonOperations(logger);
            this.config = config;
            this.contactType = common.GetOptionSetValueByContacType(contactType);
        }

        public void Run(string filePath)
        {
            Log("ImportEmailsOnly: start processing...");

            var donors = ParseFile(filePath);

            using (var serviceProxy = new OrganizationServiceProxy(config.OrganizationUri,
                                                                   config.HomeRealmUri,
                                                                   config.Credentials,
                                                                   config.DeviceCredentials))
            {
                // This statement is required to enable early-bound type support.
                serviceProxy.ServiceConfiguration.CurrentServiceEndpoint.Behaviors.Add(new ProxyTypesBehavior());

                IOrganizationService service = serviceProxy;

                common.CheckVersion(service);
                emailContactMap = common.BuildEmailContactMap(service);

                // Only rely on email map because full name will always be "Friend CTEF" in this case
                common.ImportContacts(service, donors, contactType, emailContactMap, null);
            }

            logger.Flush();
        }

        private IEnumerable<Donor> ParseFile(string filePath)
        {
            var result = new List<Donor>();

            if (!File.Exists(filePath))
            {
                Log("File not found: {0}", filePath);
                return result;
            }

            using (var reader = new StreamReader(filePath))
            {
                while (!reader.EndOfStream)
                {
                    var line = reader.ReadLine();
                    if (string.IsNullOrWhiteSpace(line) || line.IndexOf('@') < 0) continue;

                    result.Add(BuildContact(line));
                }
            }

            Log("Number of records loaded: {0}", result.Count);
            return result;
        }

        private static Donor BuildContact(string input)
        {
            // Use default values as first/last name
            return new Donor
            {
                LastName = "CTEF",
                FirstName = "Friend",
                PrimaryEmail = input.Trim().ToLowerInvariant()
            };
        }

        private void Log(string format, params object[] args)
        {
            logger.Log(format, args);
        }
    }
}
